package com.dongzili.binlog.common.deserializer;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.dongzili.binlog.custom.entity.SBrowseLogModel;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.dromara.easyes.annotation.IndexId;

import java.io.IOException;
import java.lang.reflect.Field;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;

public class CustomDeserializer extends JsonDeserializer<SBrowseLogModel> {

    @Override
    public SBrowseLogModel deserialize(JsonParser p, DeserializationContext context) throws IOException {
        ObjectMapper mapper = (ObjectMapper) p.getCodec();
        JsonNode node = mapper.readTree(p);

        SBrowseLogModel model = new SBrowseLogModel();
        Map<String, Field> fieldMap = getFieldMap(SBrowseLogModel.class);

        for (Map.Entry<String, Field> entry : fieldMap.entrySet()) {
            String jsonFieldName = entry.getKey();
            Field field = entry.getValue();
            JsonNode valueNode = node.get(jsonFieldName);
            if (valueNode != null) {
                try {
                    field.setAccessible(true);
                    if (field.getType() == LocalDateTime.class) {
                        long timestamp = valueNode.asLong();
//                        field.set(model, Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDateTime());
                        field.set(model, Instant.ofEpochMilli(timestamp).atZone(ZoneId.of("GMT")).toLocalDateTime());
                    } else if (field.getType() == Boolean.class) {
                        int intValue = valueNode.asInt();
                        field.set(model, intValue == 1);
                    } else {
                        Object value = mapper.treeToValue(valueNode, field.getType());
                        field.set(model, value);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return model;
    }

    private Map<String, Field> getFieldMap(Class<?> clazz) {
        Map<String, Field> fieldMap = new HashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            TableField tableField = field.getAnnotation(TableField.class);
            TableId tableId = field.getAnnotation(TableId.class);
            IndexId indexId = field.getAnnotation(IndexId.class);

            String fieldName = null;
            if (tableField != null) {
                fieldName = tableField.value().replace("`", "");
            } else if (tableId != null) {
                fieldName = tableId.value().replace("`", "");
            } else if (indexId != null) {
                // 这里简单处理，实际可根据 IndexId 注解进一步调整逻辑
                fieldName = field.getName();
            }
            if (fieldName != null) {
                fieldMap.put(fieldName, field);
            }
        }
        return fieldMap;
    }
}